home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_kernel_source / FS / PIPE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  11.2 KB  |  524 lines

  1. /*
  2.  *  linux/fs/pipe.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/mm.h>
  8. #include <linux/file.h>
  9. #include <linux/poll.h>
  10.  
  11. #include <asm/uaccess.h>
  12.  
  13. /*
  14.  * Define this if you want SunOS compatibility wrt braindead
  15.  * select behaviour on FIFO's.
  16.  */
  17. #ifdef __sparc__
  18. #define FIFO_SUNOS_BRAINDAMAGE
  19. #else
  20. #undef FIFO_SUNOS_BRAINDAMAGE
  21. #endif
  22.  
  23. /* We don't use the head/tail construction any more. Now we use the start/len*/
  24. /* construction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */
  25. /* Florian Coosmann (FGC)                                ^ current = 1       */
  26. /* Additionally, we now use locking technique. This prevents race condition  */
  27. /* in case of paging and multiple read/write on the same pipe. (FGC)         */
  28.  
  29.  
  30. static ssize_t pipe_read(struct file * filp, char * buf,
  31.              size_t count, loff_t *ppos)
  32. {
  33.     struct inode * inode = filp->f_dentry->d_inode;
  34.     ssize_t chars = 0, size = 0, read = 0;
  35.         char *pipebuf;
  36.  
  37.     if (ppos != &filp->f_pos)
  38.         return -ESPIPE;
  39.  
  40.     if (filp->f_flags & O_NONBLOCK) {
  41.         if (PIPE_LOCK(*inode))
  42.             return -EAGAIN;
  43.         if (PIPE_EMPTY(*inode)) {
  44.             if (PIPE_WRITERS(*inode))
  45.                 return -EAGAIN;
  46.             else
  47.                 return 0;
  48.         }
  49.     } else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
  50.         if (PIPE_EMPTY(*inode)) {
  51.             if (!PIPE_WRITERS(*inode) || !count)
  52.                 return 0;
  53.         }
  54.         if (signal_pending(current))
  55.             return -ERESTARTSYS;
  56.         interruptible_sleep_on(&PIPE_WAIT(*inode));
  57.     }
  58.     PIPE_LOCK(*inode)++;
  59.     while (count>0 && (size = PIPE_SIZE(*inode))) {
  60.         chars = PIPE_MAX_RCHUNK(*inode);
  61.         if (chars > count)
  62.             chars = count;
  63.         if (chars > size)
  64.             chars = size;
  65.         read += chars;
  66.                 pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
  67.         PIPE_START(*inode) += chars;
  68.         PIPE_START(*inode) &= (PIPE_BUF-1);
  69.         PIPE_LEN(*inode) -= chars;
  70.         count -= chars;
  71.         copy_to_user(buf, pipebuf, chars );
  72.         buf += chars;
  73.     }
  74.     PIPE_LOCK(*inode)--;
  75.     wake_up_interruptible(&PIPE_WAIT(*inode));
  76.     if (read) {
  77.         UPDATE_ATIME(inode);
  78.         return read;
  79.     }
  80.     if (PIPE_WRITERS(*inode))
  81.         return -EAGAIN;
  82.     return 0;
  83. }
  84.     
  85. static ssize_t pipe_write(struct file * filp, const char * buf,
  86.               size_t count, loff_t *ppos)
  87. {
  88.     struct inode * inode = filp->f_dentry->d_inode;
  89.     ssize_t chars = 0, free = 0, written = 0, err=0;
  90.     char *pipebuf;
  91.  
  92.     if (ppos != &filp->f_pos)
  93.         return -ESPIPE;
  94.  
  95.     if (!PIPE_READERS(*inode)) { /* no readers */
  96.         send_sig(SIGPIPE,current,0);
  97.         return -EPIPE;
  98.     }
  99.     /* if count <= PIPE_BUF, we have to make it atomic */
  100.     if (count <= PIPE_BUF)
  101.         free = count;
  102.     else
  103.         free = 1; /* can't do it atomically, wait for any free space */
  104.     up(&inode->i_sem);
  105.     if (down_interruptible(&inode->i_atomic_write)) {
  106.         down(&inode->i_sem);
  107.         return -ERESTARTSYS;
  108.     }
  109.     while (count>0) {
  110.         while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
  111.             if (!PIPE_READERS(*inode)) { /* no readers */
  112.                 send_sig(SIGPIPE,current,0);
  113.                 err = -EPIPE;
  114.                 goto errout;
  115.             }
  116.             if (signal_pending(current)) {
  117.                 err = -ERESTARTSYS;
  118.                 goto errout;
  119.             }
  120.             if (filp->f_flags & O_NONBLOCK) {
  121.                 err = -EAGAIN;
  122.                 goto errout;
  123.             }
  124.             interruptible_sleep_on(&PIPE_WAIT(*inode));
  125.         }
  126.         PIPE_LOCK(*inode)++;
  127.         while (count>0 && (free = PIPE_FREE(*inode))) {
  128.             chars = PIPE_MAX_WCHUNK(*inode);
  129.             if (chars > count)
  130.                 chars = count;
  131.             if (chars > free)
  132.                 chars = free;
  133.                         pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
  134.             written += chars;
  135.             PIPE_LEN(*inode) += chars;
  136.             count -= chars;
  137.             copy_from_user(pipebuf, buf, chars );
  138.             buf += chars;
  139.         }
  140.         PIPE_LOCK(*inode)--;
  141.         wake_up_interruptible(&PIPE_WAIT(*inode));
  142.         free = 1;
  143.     }
  144.     inode->i_ctime = inode->i_mtime = CURRENT_TIME;
  145.     mark_inode_dirty(inode);
  146. errout:
  147.     up(&inode->i_atomic_write);
  148.     down(&inode->i_sem);
  149.     return written ? written : err;
  150. }
  151.  
  152. static long long pipe_lseek(struct file * file, long long offset, int orig)
  153. {
  154.     return -ESPIPE;
  155. }
  156.  
  157. static ssize_t bad_pipe_r(struct file * filp, char * buf,
  158.               size_t count, loff_t *ppos)
  159. {
  160.     return -EBADF;
  161. }
  162.  
  163. static ssize_t bad_pipe_w(struct file * filp, const char * buf,
  164.               size_t count, loff_t *ppos)
  165. {
  166.     return -EBADF;
  167. }
  168.  
  169. static int pipe_ioctl(struct inode *pino, struct file * filp,
  170.               unsigned int cmd, unsigned long arg)
  171. {
  172.     switch (cmd) {
  173.         case FIONREAD:
  174.             return put_user(PIPE_SIZE(*pino),(int *) arg);
  175.         default:
  176.             return -EINVAL;
  177.     }
  178. }
  179.  
  180. static unsigned int pipe_poll(struct file * filp, poll_table * wait)
  181. {
  182.     unsigned int mask;
  183.     struct inode * inode = filp->f_dentry->d_inode;
  184.  
  185.     poll_wait(filp, &PIPE_WAIT(*inode), wait);
  186.     mask = POLLIN | POLLRDNORM;
  187.     if (PIPE_EMPTY(*inode))
  188.         mask = POLLOUT | POLLWRNORM;
  189.     if (!PIPE_WRITERS(*inode))
  190.         mask |= POLLHUP;
  191.     if (!PIPE_READERS(*inode))
  192.         mask |= POLLERR;
  193.     return mask;
  194. }
  195.  
  196. #ifdef FIFO_SUNOS_BRAINDAMAGE
  197. /*
  198.  * Argh!  Why does SunOS have to have different select() behaviour
  199.  * for pipes and FIFOs?  Hate, hate, hate!  SunOS lacks POLLHUP.
  200.  */
  201. static unsigned int fifo_poll(struct file * filp, poll_table * wait)
  202. {
  203.     unsigned int mask;
  204.     struct inode * inode = filp->f_dentry->d_inode;
  205.  
  206.     poll_wait(filp, &PIPE_WAIT(*inode), wait);
  207.     mask = POLLIN | POLLRDNORM;
  208.     if (PIPE_EMPTY(*inode))
  209.         mask = POLLOUT | POLLWRNORM;
  210.     if (!PIPE_READERS(*inode))
  211.         mask |= POLLERR;
  212.     return mask;
  213. }
  214. #else
  215.  
  216. #define fifo_poll pipe_poll
  217.  
  218. #endif /* FIFO_SUNOS_BRAINDAMAGE */
  219.  
  220. /*
  221.  * The 'connect_xxx()' functions are needed for named pipes when
  222.  * the open() code hasn't guaranteed a connection (O_NONBLOCK),
  223.  * and we need to act differently until we do get a writer..
  224.  */
  225. static ssize_t connect_read(struct file * filp, char * buf,
  226.                 size_t count, loff_t *ppos)
  227. {
  228.     struct inode * inode = filp->f_dentry->d_inode;
  229.     if (PIPE_EMPTY(*inode) && !PIPE_WRITERS(*inode))
  230.         return 0;
  231.     filp->f_op = &read_fifo_fops;
  232.     return pipe_read(filp,buf,count,ppos);
  233. }
  234.  
  235. static unsigned int connect_poll(struct file * filp, poll_table * wait)
  236. {
  237.     struct inode * inode = filp->f_dentry->d_inode;
  238.  
  239.     poll_wait(filp, &PIPE_WAIT(*inode), wait);
  240.     if (!PIPE_EMPTY(*inode)) {
  241.         filp->f_op = &read_fifo_fops;
  242.         return POLLIN | POLLRDNORM;
  243.     }
  244.     if (PIPE_WRITERS(*inode))
  245.         filp->f_op = &read_fifo_fops;
  246.     return POLLOUT | POLLWRNORM;
  247. }
  248.  
  249. static int pipe_release(struct inode * inode)
  250. {
  251.     if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
  252.         free_page((unsigned long) PIPE_BASE(*inode));
  253.         PIPE_BASE(*inode) = NULL;
  254.     }
  255.     wake_up_interruptible(&PIPE_WAIT(*inode));
  256.     return 0;
  257. }
  258.  
  259. static int pipe_read_release(struct inode * inode, struct file * filp)
  260. {
  261.     PIPE_READERS(*inode)--;
  262.     return pipe_release(inode);
  263. }
  264.  
  265. static int pipe_write_release(struct inode * inode, struct file * filp)
  266. {
  267.     PIPE_WRITERS(*inode)--;
  268.     return pipe_release(inode);
  269. }
  270.  
  271. static int pipe_rdwr_release(struct inode * inode, struct file * filp)
  272. {
  273.     if (filp->f_mode & FMODE_READ)
  274.         PIPE_READERS(*inode)--;
  275.     if (filp->f_mode & FMODE_WRITE)
  276.         PIPE_WRITERS(*inode)--;
  277.     return pipe_release(inode);
  278. }
  279.  
  280. static int pipe_read_open(struct inode * inode, struct file * filp)
  281. {
  282.     PIPE_READERS(*inode)++;
  283.     return 0;
  284. }
  285.  
  286. static int pipe_write_open(struct inode * inode, struct file * filp)
  287. {
  288.     PIPE_WRITERS(*inode)++;
  289.     return 0;
  290. }
  291.  
  292. static int pipe_rdwr_open(struct inode * inode, struct file * filp)
  293. {
  294.     if (filp->f_mode & FMODE_READ)
  295.         PIPE_READERS(*inode)++;
  296.     if (filp->f_mode & FMODE_WRITE)
  297.         PIPE_WRITERS(*inode)++;
  298.     return 0;
  299. }
  300.  
  301. /*
  302.  * The file_operations structs are not static because they
  303.  * are also used in linux/fs/fifo.c to do operations on FIFOs.
  304.  */
  305. struct file_operations connecting_fifo_fops = {
  306.     pipe_lseek,
  307.     connect_read,
  308.     bad_pipe_w,
  309.     NULL,        /* no readdir */
  310.     connect_poll,
  311.     pipe_ioctl,
  312.     NULL,        /* no mmap on pipes.. surprise */
  313.     pipe_read_open,
  314.     NULL,        /* flush */
  315.     pipe_read_release,
  316.     NULL
  317. };
  318.  
  319. struct file_operations read_fifo_fops = {
  320.     pipe_lseek,
  321.     pipe_read,
  322.     bad_pipe_w,
  323.     NULL,        /* no readdir */
  324.     fifo_poll,
  325.     pipe_ioctl,
  326.     NULL,        /* no mmap on pipes.. surprise */
  327.     pipe_read_open,
  328.     NULL,        /* flush */
  329.     pipe_read_release,
  330.     NULL
  331. };
  332.  
  333. struct file_operations write_fifo_fops = {
  334.     pipe_lseek,
  335.     bad_pipe_r,
  336.     pipe_write,
  337.     NULL,        /* no readdir */
  338.     fifo_poll,
  339.     pipe_ioctl,
  340.     NULL,        /* mmap */
  341.     pipe_write_open,
  342.     NULL,        /* flush */
  343.     pipe_write_release,
  344.     NULL
  345. };
  346.  
  347. struct file_operations rdwr_fifo_fops = {
  348.     pipe_lseek,
  349.     pipe_read,
  350.     pipe_write,
  351.     NULL,        /* no readdir */
  352.     fifo_poll,
  353.     pipe_ioctl,
  354.     NULL,        /* mmap */
  355.     pipe_rdwr_open,
  356.     NULL,        /* flush */
  357.     pipe_rdwr_release,
  358.     NULL
  359. };
  360.  
  361. struct file_operations read_pipe_fops = {
  362.     pipe_lseek,
  363.     pipe_read,
  364.     bad_pipe_w,
  365.     NULL,        /* no readdir */
  366.     pipe_poll,
  367.     pipe_ioctl,
  368.     NULL,        /* no mmap on pipes.. surprise */
  369.     pipe_read_open,
  370.     NULL,        /* flush */
  371.     pipe_read_release,
  372.     NULL
  373. };
  374.  
  375. struct file_operations write_pipe_fops = {
  376.     pipe_lseek,
  377.     bad_pipe_r,
  378.     pipe_write,
  379.     NULL,        /* no readdir */
  380.     pipe_poll,
  381.     pipe_ioctl,
  382.     NULL,        /* mmap */
  383.     pipe_write_open,
  384.     NULL,        /* flush */
  385.     pipe_write_release,
  386.     NULL
  387. };
  388.  
  389. struct file_operations rdwr_pipe_fops = {
  390.     pipe_lseek,
  391.     pipe_read,
  392.     pipe_write,
  393.     NULL,        /* no readdir */
  394.     pipe_poll,
  395.     pipe_ioctl,
  396.     NULL,        /* mmap */
  397.     pipe_rdwr_open,
  398.     NULL,        /* flush */
  399.     pipe_rdwr_release,
  400.     NULL
  401. };
  402.  
  403. static struct inode * get_pipe_inode(void)
  404. {
  405.     extern struct inode_operations pipe_inode_operations;
  406.     struct inode *inode = get_empty_inode();
  407.  
  408.     if (inode) {
  409.         unsigned long page = __get_free_page(GFP_USER);
  410.  
  411.         if (!page) {
  412.             iput(inode);
  413.             inode = NULL;
  414.         } else {
  415.             PIPE_BASE(*inode) = (char *) page;
  416.             inode->i_op = &pipe_inode_operations;
  417.             PIPE_WAIT(*inode) = NULL;
  418.             PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
  419.             PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
  420.             PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
  421.             PIPE_LOCK(*inode) = 0;
  422.             /*
  423.              * Mark the inode dirty from the very beginning,
  424.              * that way it will never be moved to the dirty
  425.              * list because "mark_inode_dirty()" will think
  426.              * that it already _is_ on the dirty list.
  427.              */
  428.             inode->i_state = I_DIRTY;
  429.             inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
  430.             inode->i_uid = current->fsuid;
  431.             inode->i_gid = current->fsgid;
  432.             inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  433.             inode->i_blksize = PAGE_SIZE;
  434.         }
  435.     }
  436.     return inode;
  437. }
  438.  
  439. struct inode_operations pipe_inode_operations = {
  440.     &rdwr_pipe_fops,
  441.     NULL,            /* create */
  442.     NULL,            /* lookup */
  443.     NULL,            /* link */
  444.     NULL,            /* unlink */
  445.     NULL,            /* symlink */
  446.     NULL,            /* mkdir */
  447.     NULL,            /* rmdir */
  448.     NULL,            /* mknod */
  449.     NULL,            /* rename */
  450.     NULL,            /* readlink */
  451.     NULL,            /* readpage */
  452.     NULL,            /* writepage */
  453.     NULL,            /* bmap */
  454.     NULL,            /* truncate */
  455.     NULL            /* permission */
  456. };
  457.  
  458. int do_pipe(int *fd)
  459. {
  460.     struct inode * inode;
  461.     struct file *f1, *f2;
  462.     int error;
  463.     int i,j;
  464.  
  465.     error = -ENFILE;
  466.     f1 = get_empty_filp();
  467.     if (!f1)
  468.         goto no_files;
  469.  
  470.     f2 = get_empty_filp();
  471.     if (!f2)
  472.         goto close_f1;
  473.  
  474.     inode = get_pipe_inode();
  475.     if (!inode)
  476.         goto close_f12;
  477.  
  478.     error = get_unused_fd();
  479.     if (error < 0)
  480.         goto close_f12_inode;
  481.     i = error;
  482.  
  483.     error = get_unused_fd();
  484.     if (error < 0)
  485.         goto close_f12_inode_i;
  486.     j = error;
  487.  
  488.     error = -ENOMEM;
  489.     f1->f_dentry = f2->f_dentry = dget(d_alloc_root(inode, NULL));
  490.     if (!f1->f_dentry)
  491.         goto close_f12_inode_i_j;
  492.  
  493.     /* read file */
  494.     f1->f_pos = f2->f_pos = 0;
  495.     f1->f_flags = O_RDONLY;
  496.     f1->f_op = &read_pipe_fops;
  497.     f1->f_mode = 1;
  498.  
  499.     /* write file */
  500.     f2->f_flags = O_WRONLY;
  501.     f2->f_op = &write_pipe_fops;
  502.     f2->f_mode = 2;
  503.  
  504.     fd_install(i, f1);
  505.     fd_install(j, f2);
  506.     fd[0] = i;
  507.     fd[1] = j;
  508.     return 0;
  509.  
  510. close_f12_inode_i_j:
  511.     put_unused_fd(j);
  512. close_f12_inode_i:
  513.     put_unused_fd(i);
  514. close_f12_inode:
  515.     free_page((unsigned long) PIPE_BASE(*inode));
  516.     iput(inode);
  517. close_f12:
  518.     put_filp(f2);
  519. close_f1:
  520.     put_filp(f1);
  521. no_files:
  522.     return error;    
  523. }
  524.